#pragma once

#include <iostream>
#include <thread>
#include <vector>
#include <queue>
#include <mutex>
#include <condition_variable>
using namespace std;

const int defaultnum = 5;

template <class T>
class ThreadPool
{
public:
    ThreadPool(int num = defaultnum) : num_(num), isrunning(false)
    {
        // qt_.push(3);
    }
    bool IsQueueEmpty()
    {

        return qt_.empty();
    }
    void HandlerTask(int threadid)
    {

        // 判断也是访问共享资源
        // 判断队列中有没有任务
        // 加锁
        while (true)
        {
            unique_lock<mutex> lock(mutex_);
            while (IsQueueEmpty())
            {
                cond_.wait(lock);
            }
            cout << "threadid is : " << threadid << " :  ";
            // 处理任务
            //  打印一下
            // 从队列中取出任务
            T t = Pop();
            lock.unlock();
            cout << "消费了一个任务 : " << t << endl;
        }
    }
    void Start()
    {
        if (isrunning)
            return;
        // 把线程创建出来
        for (int i = 0; i < num_; ++i)
        {
            tids_.emplace_back(thread(&ThreadPool::HandlerTask, this, i + 1));
            cout << "i: " << i << endl;
        }
        isrunning = true;
    }
    // 往线程池放入任务
    void Push(const T &in)
    {
        // 加锁

        lock_guard<mutex> lock(mutex_);
        qt_.push(in);
        cond_.notify_one();
    }
    // 从线程池获取任务
    T Pop()
    {
        T t = qt_.front();
        qt_.pop();
        return t;
    }
    ~ThreadPool()
    {

        isrunning = false;

        cond_.notify_all();
        for (int i = 0; i < num_; ++i)
        {
            tids_[i].join();
        }
    }

private:
    vector<thread> tids_;
    queue<T> qt_;
    int num_;
    mutex mutex_;
    condition_variable cond_;
    bool isrunning;
};